【アプリもインフラも1つの言語で書ける】Wingのチュートリアルをやってみる
最近Infrastructure from Code (IfC) という概念を知りました。
とりあえず、触って雰囲気を掴みたいと思いWingのチュートリアルをやってみました。
- Infrastructure from Code (IfC) ツールまとめ - maybe daily dev notes
- IxC: Infrastructure as Code, from Code, with Code - The Architect Elevator
Wingとは
Wingとはクラウド向けのプログラミング言語です。
WingLangという独自の言語を使って、インフラとアプリを1つの言語で同時にコーディングできます。
公式サイト内のイントロダクションの動画が分かりやすくて、おすすめです。(15分と短くて見やすいです)
WingLangをコンパイルして、AWSやGCP、Azureなどに対応したTerraformやCDK、CFnを生成することができます。(2023/8時点では、AWSとTerraformに対応しています。)
AWS SDK等を使ったアプリケーションコードに関しても、同様に生成されます。
下記は実際のコードと作成されるAWSリソースです。
チュートリアルをやってみる
今回はローカルにインストールしてやってみます。エディタはVSCodeを使います。
ブラウザで試せるPlayGroudも用意されています。
準備
以下をインストールしておきます。
- Node.js(>= 18.13.0)
- Winglang
- (あると便利)Winglang VSCode拡張機能
- Terraform
- AWS CLI
AWS上にデプロイする際には、winglangからtfファイルを生成してTerraformを使ってデプロイします。
そのため、TerraformやAWS CLIも必要になります。
アプリケーションの作成
以下、ファイルを用意します。
bring cloud; let bucket = new cloud.Bucket(); let counter = new cloud.Counter(initial: 1); let queue = new cloud.Queue(); queue.setConsumer(inflight (message: str) => { let index = counter.inc(); bucket.put("wing-${index}.txt", "Hello, ${message}"); log("file wing-${index}.txt created"); });
コードの内容としては、メッセージにキューが追加されるたびにカウントを追加してバケットにwing-${index}.txt
を追加するものです。
Winglangという独自言語を使います。
WinglangにはPreflightとInflightという概念があります。
詳細は公式ドキュメントにて説明されています。
ざっくりいうと、Preflightはインフラコード、Inflightはアプリケーションコードという理解で良いかと思います。
上記のコード中では、inflight
から始まるブロック(ハイライト部分)がInflightでほかはPreflightになります。
ローカル実行
Wingではローカルで実行して、リソースの動作を試すことができます。
以下のコマンドを実行すると、Wingコンソールがブラウザで開かれます。
$ wing it hello.w
ちなみにWingの拡張機能を使っている場合、VSCodeで開くこともできます。
コマンドパレットからOpen in Wing Console
を選択すると以下のように表示されます。
リソースを可視化してくれるだけでも凄いんですが、データの入出力をテストすることができます。
今回のコードであれば、以下の一連の流れをローカルで確認できます。
- キューにメッセージを送信
- カウンターがカウントをインクリメント
- バケットにファイルを保存
キューに「test」というメッセージを送信します。
カウンターを確認すると、カウントがインクリメントされています。
バケットを確認するとwing-1.txt
というファイルが作成されることを確認できます。
ファイルの内容にもメッセージで渡した値が入っていることを確認できました。
クラウドリソースのローカルテストは悩みどころが多いので、助かりますね。
AWS上にデプロイ
現時点では、Terraformを使ったAWSへのデプロイがサポートされています。
将来的には、AzureやGoogle Cloud、プロビジョニングツールとしてCFn等をサポートされるそうです。
Wingのファイルをtfファイルに変換します。
$ wing compile --target tf-aws hello.w
tfファイルはtarget/hello.tfaws
配下に作成されます。
main.tf.json
にリソースの定義が書いています。
貼ると長くなるので省略しますが、DynamoDBやSQS、S3が定義されています。 winglangは10行程度ですが、200行程度(jsonですが)の定義が作成されました。
あとは、ディレクトリに移動してterraformを使ってリソースを作成します。
$ cd target/hello.tfaws $ export AWS_REGION="ap-northeast-1" $ # AWS認証情報をセット $ terraform init $ terraform apply
動作確認
ローカルと同様に確認していきます。
- キューにメッセージを送信
- カウンターがカウントをインクリメント
- バケットにファイルを保存
実際に作成されるAWSリソースと関連付けると以下になります。
まずはキュー(SQS)でメッセージを送信します。
カウンタとバケットを更新する用のLambdaが実行されていました。
カウンタ(DynamoDB)のcounterは2になっており、インクリメントされたことが分かります。
バケットを確認すると、wing-1.txt
が作成されていました。
ファイルの中身も想定どおりの値になっています。
StateファイルをS3バックエンドに保管
デフォルトではStateファイルのバックエンドがローカルになります。
ローカルではCI/CDや複数人で作業をする際に、困ってしまいます。
ドキュメントを確認すると、解決策ありました。
バックエンドにS3を利用可能でした。詳細はドキュメント内で確認できます。
ざっくり書くと、以下のステップでできます。
plugin.static-backend.js
にバックエンドを定義wing compile
する
ちなみに、CI/CDに関してもGitHub Actionsを例にしてドキュメントに説明されていました。
おわりに
Wingのチュートリアルについてでした。
かなり少ない記述でインフラとアプリを作成することができます。ローカルのシミュレータも使いやすくて便利でした。
高度に抽象化されており、特定のユースケースでは開発効率がとても高そうです。
今後の発展が楽しみです。
以上、AWS事業本部の佐藤(@chari7311)でした。